package com.cook.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cook.dto.recipes.IngredientDTO;
import com.cook.entity.Ingredients;
import com.cook.service.IngredientsService;
import com.cook.mapper.IngredientsMapper;
import com.cook.vo.recipes.IngredientVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
* @author black-white spider
* @description 针对表【ingredients(食谱食材表)】的数据库操作Service实现
* @createDate 2025-10-27 19:54:38
*/
@Service
@Slf4j
public class IngredientsServiceImpl extends ServiceImpl<IngredientsMapper, Ingredients>
    implements IngredientsService{
    @Autowired
    private IngredientsMapper ingredientsMapper;

    @Override
    public List<IngredientVO> getIngredientsByRecipeId(Long recipeId) {
        log.info("查询食谱食材: recipeId={}", recipeId);

        validateRecipeId(recipeId);

        try {
            List<IngredientVO> ingredients = ingredientsMapper.selectByRecipeId(recipeId);
            log.info("查询到 {} 种食材", ingredients.size());
            return ingredients;
        } catch (Exception e) {
            log.error("查询食材列表失败: recipeId={}", recipeId, e);
            throw new RuntimeException("查询食材失败");
        }
    }

    @Override
    public IngredientVO getIngredientById(Long ingredientId) {
        log.info("查询食材详情: ingredientId={}", ingredientId);

        validateIngredientId(ingredientId);

        try {
            IngredientVO ingredient = ingredientsMapper.selectById(ingredientId);
            if (ingredient == null) {
                log.warn("食材不存在: ingredientId={}", ingredientId);
                throw new RuntimeException("食材不存在");
            }
            return ingredient;
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            log.error("查询食材详情失败: ingredientId={}", ingredientId, e);
            throw new RuntimeException("查询食材失败");
        }
    }

    @Override
    @Transactional
    public Long addIngredient(IngredientDTO ingredientDTO) {
        log.info("添加食材: recipeId={}, name={}", ingredientDTO.getRecipeId(), ingredientDTO.getName());

        validateIngredientsDTO(ingredientDTO);

        try {
            Ingredients ingredient = new Ingredients();
            BeanUtils.copyProperties(ingredientDTO, ingredient);

            int result = ingredientsMapper.insertIngredient(ingredient);
            if (result > 0) {
                log.info("食材添加成功: ingredientId={}", ingredient.getIngredientId());
                return ingredient.getIngredientId();
            } else {
                throw new RuntimeException("添加食材失败");
            }
        } catch (Exception e) {
            log.error("添加食材失败: ", e);
            throw new RuntimeException("添加食材失败");
        }
    }

    @Override
    @Transactional
    public boolean batchAddIngredients(List<IngredientDTO> ingredientDTOList) {
        log.info("批量添加食材: 共 {} 种", ingredientDTOList.size());

        if (ingredientDTOList == null || ingredientDTOList.isEmpty()) {
            throw new IllegalArgumentException("食材列表不能为空");
        }

        try {
            // 验证所有DTO
            for (IngredientDTO dto : ingredientDTOList) {
                validateIngredientsDTO(dto);
            }

            // DTO转Entity
            List<Ingredients> ingredientsList = ingredientDTOList.stream()
                    .map(dto -> {
                        Ingredients ingredient = new Ingredients();
                        BeanUtils.copyProperties(dto, ingredient);
                        return ingredient;
                    })
                    .collect(Collectors.toList());

            int result = ingredientsMapper.batchInsertIngredients(ingredientsList);
            boolean success = result == ingredientDTOList.size();

            if (success) {
                log.info("批量添加食材成功: 共 {} 种", result);
            } else {
                log.warn("批量添加食材部分失败: 成功 {} 种，总共 {} 种", result, ingredientDTOList.size());
            }

            return result > 0;
        } catch (Exception e) {
            log.error("批量添加食材失败: ", e);
            throw new RuntimeException("批量添加食材失败");
        }
    }

    @Override
    @Transactional
    public boolean updateIngredient(IngredientDTO ingredientDTO) {
        log.info("更新食材: ingredientId={}", ingredientDTO.getIngredientId());

        validateIngredientsDTO(ingredientDTO);
        validateIngredientId(ingredientDTO.getIngredientId());

        try {
            Ingredients ingredient = new Ingredients();
            BeanUtils.copyProperties(ingredientDTO, ingredient);

            int result = ingredientsMapper.updateIngredient(ingredient);
            boolean success = result > 0;

            if (success) {
                log.info("食材更新成功: ingredientId={}", ingredient.getIngredientId());
            } else {
                log.warn("食材更新失败: ingredientId={}", ingredient.getIngredientId());
            }

            return success;
        } catch (Exception e) {
            log.error("更新食材失败: ", e);
            throw new RuntimeException("更新食材失败");
        }
    }

    @Override
    @Transactional
    public boolean deleteIngredient(Long ingredientId) {
        log.info("删除食材: ingredientId={}", ingredientId);

        validateIngredientId(ingredientId);

        try {
            int result = ingredientsMapper.deleteById(ingredientId);
            boolean success = result > 0;

            if (success) {
                log.info("食材删除成功: ingredientId={}", ingredientId);
            } else {
                log.warn("食材删除失败: ingredientId={}", ingredientId);
            }

            return success;
        } catch (Exception e) {
            log.error("删除食材失败: ingredientId={}", ingredientId, e);
            throw new RuntimeException("删除食材失败");
        }
    }

    @Override
    @Transactional
    public boolean deleteIngredientsByRecipeId(Long recipeId) {
        log.info("删除食谱所有食材: recipeId={}", recipeId);

        validateRecipeId(recipeId);

        try {
            int result = ingredientsMapper.deleteByRecipeId(recipeId);
            boolean success = result >= 0; // 可能为0（没有食材）

            if (success) {
                log.info("食谱食材删除成功: recipeId={}, 删除 {} 种食材", recipeId, result);
            } else {
                log.warn("食谱食材删除失败: recipeId={}", recipeId);
            }

            return success;
        } catch (Exception e) {
            log.error("删除食谱食材失败: recipeId={}", recipeId, e);
            throw new RuntimeException("删除食材失败");
        }
    }

    @Override
    @Transactional
    public boolean copyIngredientsToRecipe(Long sourceRecipeId, Long targetRecipeId) {
        log.info("复制食材: sourceRecipeId={}, targetRecipeId={}", sourceRecipeId, targetRecipeId);

        validateRecipeId(sourceRecipeId);
        validateRecipeId(targetRecipeId);

        try {
            // 查询源食谱的食材
            List<IngredientVO> sourceIngredients = getIngredientsByRecipeId(sourceRecipeId);

            if (sourceIngredients.isEmpty()) {
                log.info("源食谱没有食材，无需复制");
                return true;
            }

            // 转换为DTO并更新recipeId
            List<IngredientDTO> targetIngredients = sourceIngredients.stream()
                    .map(vo -> {
                        IngredientDTO dto = new IngredientDTO();
                        BeanUtils.copyProperties(vo, dto);
                        dto.setRecipeId(targetRecipeId);
                        dto.setIngredientId(null); // 清除ID，生成新的
                        return dto;
                    })
                    .collect(Collectors.toList());

            return batchAddIngredients(targetIngredients);
        } catch (Exception e) {
            log.error("复制食材失败: ", e);
            throw new RuntimeException("复制食材失败");
        }
    }

    /**
     * 验证食材ID
     */
    private void validateIngredientId(Long ingredientId) {
        if (ingredientId == null || ingredientId <= 0) {
            throw new IllegalArgumentException("食材ID不能为空");
        }
    }

    /**
     * 验证食谱ID
     */
    private void validateRecipeId(Long recipeId) {
        if (recipeId == null || recipeId <= 0) {
            throw new IllegalArgumentException("食谱ID不能为空");
        }
    }

    /**
     * 验证食材DTO
     */
    private void validateIngredientsDTO(IngredientDTO dto) {
        if (dto == null) {
            throw new IllegalArgumentException("食材数据不能为空");
        }
        if (dto.getRecipeId() == null || dto.getRecipeId() <= 0) {
            throw new IllegalArgumentException("食谱ID不能为空");
        }
        if (dto.getName() == null || dto.getName().trim().isEmpty()) {
            throw new IllegalArgumentException("食材名称不能为空");
        }
        if (dto.getName().length() > 100) {
            throw new IllegalArgumentException("食材名称过长");
        }
        if (dto.getQuantity() != null && dto.getQuantity().length() > 50) {
            throw new IllegalArgumentException("食材数量过长");
        }
        if (dto.getOptional() == null) {
            dto.setOptional(0); // 默认非可选
        }
    }
}




